<?php


namespace app\common\library;


/**
 * 微信小程序二维码
 */
class WxCode
{

    protected $AppId = 'wx12de1bffca232a59';

    protected $AppSecret = 'e9137107a6473808265af981b08bbd00';

    public function __construct($AppId = 'wx12de1bffca232a59', $AppSecret = 'e9137107a6473808265af981b08bbd00')
    {
        $this->AppId = $AppId;
        $this->AppSecret = $AppSecret;
    }


    // 获取用户推广的小程序二维码
    public function getUserCode($userId, $invite_code)
    {
        $str = 'invite_code=' . $invite_code;
        $result = $this->getWxCode($str);
        if (is_int($result)) {
            return $result;
        } else {
            $image = '/' . $result;
            model('app\common\model\User')->where(['id' => $userId])->setField('qr_code', $image);
            return $image;
        }
    }

    /**
     * 生成微信二维码
     *
     * @param $str string 二维码数据
     * @param $action_name string 二维码类型，QR_SCENE为临时的整型参数值，QR_STR_SCENE为临时的字符串参数值，QR_LIMIT_SCENE为永久的整型参数值，QR_LIMIT_STR_SCENE为永久的字符串参数值
     * @param $is_img bool 获取图片或base64图片流
     */
    public function showQrCode($str = '', $action_name = 'QR_LIMIT_SCENE', $is_img = true)
    {
        $AppId = $this->AppId;
        $AppSecret = $this->AppSecret;
        $url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=' . $AppId . '&secret=' . $AppSecret;

        $access = \fast\Http::get($url);
        $data = json_decode($access, true);
        $access_token = $data['access_token'];
        $request_url = 'https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=' . $access_token;
        $request_data = [
            'action_name' => $action_name,
            'action_info' => [
                'scene' => $str,
            ],
        ];
        if ($action_name == 'QR_SCENE' || $action_name = 'QR_STR_SCENE') {
            $request_data['expire_seconds'] = 604800;//该二维码有效时间，以秒为单位。 最大不超过2592000（即30天），此字段如果不填，则默认有效期为30秒。
        }
        $result = $this->doPostJson($request_url, $request_data);
        $result = json_decode($result, true);
        $ticket = urlencode($result['ticket']);
        $request_url_2 = 'https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=' . $ticket;
        $access_2 = \fast\Http::get($request_url_2);

        $image = base64_encode($access_2);
        $cdn_result = $this->image($image, false);

        return $cdn_result;
    }

    /**
     * 生成小程序太阳码
     */
    public function getWxCode($str, $page = '')
    {
        $AppId = $this->AppId;
        $AppSecret = $this->AppSecret;
        $url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=' . $AppId . '&secret=' . $AppSecret;

        $access = \fast\Http::get($url);
        $data = json_decode($access, true);
        $access_token = $data['access_token'];
        $request_url = 'https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=' . $access_token;
        $request_data = [
            'scene' => $str,
        ];
        if (!empty($page)) {
            $request_data['page'] = $page;
        }
        $result = $this->doPostJson($request_url, $request_data);
        // ob_clean();
        // header('Content-Type: image/png; charset=UTF-8');
        // echo $result;exit;
        $image = base64_encode($result);
        $cdn_result = $this->image($image);

        return $cdn_result;
    }

    /**
     * @param $is_img bool 获取图片或base64图片流
     */
    public function image($image, $is_img = true)
    {
        //目录的upload文件夹下
        $up_dir = "uploads/" . date('Ymd', time()) . "/";  //创建目录

        if (!file_exists($up_dir)) {
            mkdir($up_dir, 0777, true);
        }
        $base64_img = trim($image);

        if (preg_match('/^(data:\s*image\/(\w+);base64,)/', 'data:image/jpg;base64,' . $base64_img, $result)) {
            // 获取base64数据流
            if (!$is_img) {
                return 'data:image/jpg;base64,' . $base64_img;
            }
            $type = $result[2];
            if (in_array($type, array('pjpeg', 'jpeg', 'jpg', 'gif', 'bmp', 'png'))) {

                $new_file = $up_dir . time() . '.' . $type;
                if (file_put_contents($new_file, base64_decode(str_replace($result[1], '', $base64_img)))) {
                    $img_path = str_replace('../../..', '', $new_file);
                    return $img_path;
                } else {
                    return 10002;
                }
            } else {
                //文件类型错误
                return 10001;
            }
        }
        return 10000;
    }

    // 通过POST方式发送json数据
    static public function doPostJson($url = '', $param = [], $contentType = 'json')
    {
        $ch = curl_init();
        // 请求地址
        curl_setopt($ch, CURLOPT_URL, $url);
        // 请求参数类型
        $param = $contentType == 'json' ? json_encode($param) : http_build_query($param);
        // 关闭https验证
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
        // post提交
        if ($param) {
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $param);
        }
        // 返回的数据是否自动显示
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        // 执行并接收响应结果
        $output = curl_exec($ch);
        // 关闭curl
        curl_close($ch);
        return $output !== false ? $output : false;
    }

    /**
     * 海报图
     *
     */
    public function posterImage($user_id, $returnStr = true)
    {
        $user = model('app\common\model\User')->get($user_id);
        $invite_code = $user->invite_code;
        $qr_code = $user->qr_code;
        if (!$qr_code) {
            $qr_code = $this->getUserCode($user_id, $invite_code);
        }

        $fontPath = ROOT_PATH . '/public/assets/fonts/PingFang Medium.ttf';
        $boldFontPath = ROOT_PATH . '/public/assets/fonts/Founder thick black song simplified.ttf';
        $system = model('app\common\model\SystemModel')->get(1);
        $config = [
            'text' => [
                [//用户信息
                    'text' => filterEmoji($user->nickname),
                    'left' => 240,
                    'top' => -300,
                    'fontPath' => $fontPath,     //字体文件
                    'fontSize' => 20,             //字号
                    'fontColor' => '98,98,98',       //字体颜色
                    'angle' => 0,
                ],
                [//用户信息
                    'text' => '推荐给你',
                    'left' => 240,
                    'top' => -260,
                    'fontPath' => $fontPath,     //字体文件
                    'fontSize' => 20,             //字号
                    'fontColor' => '98,98,98',       //字体颜色
                    'angle' => 0,
                ],
                [
                    'text' => '长按识别二维码进入',
                    'left' => 240,
                    'top' => -140,
                    'fontPath' => $fontPath,     //字体文件
                    'fontSize' => 18,             //字号
                    'fontColor' => '98,98,98',       //字体颜色
                    'angle' => 0,
                ],
                [
                    'text' => '匠人丙乾小程序',
                    'left' => 240,
                    'top' => -100,
                    'fontPath' => $fontPath,     //字体文件
                    'fontSize' => 18,             //字号
                    'fontColor' => '98,98,98',       //字体颜色
                    'angle' => 0,
                ],
            ],
            'image' => [
                [//海报上部分图
                    'url' => ImageAddDomainNoS($system->bg_invite_image),
                    'stream' => 0,//图片资源是否是字符串图像流
                    'left' => 45,
                    'top' => 40,
                    'right' => 0,
                    'bottom' => 0,
                    'width' => 630,
                    'height' => 650,
                    'opacity' => 100,
                ],
                [//用户信息
                    'url' => ImageAddDomainNoS($user->avatar),
                    'stream' => 0,
                    'left' => 85,
                    'top' => -240,
                    'right' => 0,
                    'bottom' => 0,
                    'width' => 100,
                    'height' => 100,
                    'opacity' => 100,
                    'radius' => 15,
                ],
                [//二维码信息
                    'url' => ImageAddDomainNoS($qr_code),
                    'stream' => 0,
                    'left' => 65,
                    'top' => -55,
                    'right' => 0,
                    'bottom' => 0,
                    'width' => 150,
                    'height' => 150,
                    'opacity' => 100,
                ],
            ],
            'background' => ImageAddDomainNoS($system->bg_image)          //背景图
        ];

        $file_dir = 'uploads/qrcode/' . date('Ym') . '/';
        create($file_dir);
        $filename =  '/' . $file_dir . time() . $invite_code . '.png';
        $file_path = ROOT_PATH . '/public/' . $filename;

        $url = $this->createPoster($config, $file_path);
        if($returnStr) {
            return $filename;
        }
        echo "<img src='".ImageAddDomain($filename)."'>";
    }


    /**
     * 生成宣传海报
     * @param array  参数,包括图片和文字
     * @param string  $filename 生成海报文件名,不传此参数则不生成文件,直接输出图片
     * @return [type] [description]
     */
    public function createPoster($config=array(),$filename="")
    {
        //如果要看报什么错，可以先注释调这个header
        if(empty($filename)) header("content-type: image/png");
        $imageDefault = array(
            'left'=>0,
            'top'=>0,
            'right'=>0,
            'bottom'=>0,
            'width'=>100,
            'height'=>100,
            'opacity'=>100
        );
        $textDefault = array(
            'text'=>'',
            'left'=>0,
            'top'=>0,
            'fontSize'=>32,       //字号
            'fontColor'=>'255,255,255', //字体颜色
            'angle'=>0,
        );
        $background = $config['background'];//海报最底层得背景
        //背景方法
        $backgroundInfo = getimagesize($background);
        $backgroundFun = 'imagecreatefrom'.image_type_to_extension($backgroundInfo[2], false);
        $background = $backgroundFun($background);
        $backgroundWidth = imagesx($background);  //背景宽度
        $backgroundHeight = imagesy($background);  //背景高度
        $imageRes = imageCreatetruecolor($backgroundWidth,$backgroundHeight);
        $color = imagecolorallocate($imageRes, 0, 0, 0);
        imagefill($imageRes, 0, 0, $color);
        // imageColorTransparent($imageRes, $color);  //颜色透明
        imagecopyresampled($imageRes,$background,0,0,0,0,imagesx($background),imagesy($background),imagesx($background),imagesy($background));
        //处理了图片
        if(!empty($config['image'])){
            foreach ($config['image'] as $key => $val) {
                $val = array_merge($imageDefault,$val);
                $info = getimagesize($val['url']);
                $function = 'imagecreatefrom'.image_type_to_extension($info[2], false);
                if($val['stream']){   //如果传的是字符串图像流
                    $info = getimagesizefromstring($val['url']);
                    $function = 'imagecreatefromstring';
                }
                $res = $function($val['url']);
                $resWidth = $info[0];
                $resHeight = $info[1];
                //建立画板 ，缩放图片至指定尺寸
                $canvas=imagecreatetruecolor($val['width'], $val['height']);
                imagefill($canvas, 0, 0, $color);
                //关键函数，参数（目标资源，源，目标资源的开始坐标x,y, 源资源的开始坐标x,y,目标资源的宽高w,h,源资源的宽高w,h）
                imagecopyresampled($canvas, $res, 0, 0, 0, 0, $val['width'], $val['height'],$resWidth,$resHeight);
                $val['left'] = $val['left']<0?$backgroundWidth- abs($val['left']) - $val['width']:$val['left'];
                $val['top'] = $val['top']<0?$backgroundHeight- abs($val['top']) - $val['height']:$val['top'];
                //放置图像
                imagecopymerge($imageRes,$canvas, $val['left'],$val['top'],$val['right'],$val['bottom'],$val['width'],$val['height'],$val['opacity']);//左，上，右，下，宽度，高度，透明度
            }
        }
        //处理文字
        if(!empty($config['text'])){
            foreach ($config['text'] as $key => $val) {
                $val = array_merge($textDefault,$val);
                list($R,$G,$B) = explode(',', $val['fontColor']);
                $fontColor = imagecolorallocate($imageRes, $R, $G, $B);
                $val['left'] = $val['left']<0?$backgroundWidth- abs($val['left']):$val['left'];
                $val['top'] = $val['top']<0?$backgroundHeight- abs($val['top']):$val['top'];
                imagettftext($imageRes,$val['fontSize'],$val['angle'],$val['left'],$val['top'],$fontColor,$val['fontPath'],$val['text']);
            }
        }
        //生成图片
        if(!empty($filename)){
            $res = imagejpeg ($imageRes,$filename,90); //保存到本地
            imagedestroy($imageRes);
            if(!$res) return false;
            return $filename;
        }else{
            imagejpeg ($imageRes);     //在浏览器上显示
            imagedestroy($imageRes);
        }
    }


    /**
     * 生成普通二维码
     * @param array $params 二维码参数
     * @param string $file_catalog 文件存放目录
     * @return string $filename 文件相对路径
    */
    public function createQrcode(array $params, string $file_catalog): string
    {
        $params_str = '';
        foreach ($params as $key => $value) {
            $params_str .= $key . '=' . $value . "&";
        }
//        $params_str = implode('&',$params);
        $file_dir = "uploads/$file_catalog/" . date('Ym') . '/' . date('d') .'/';
        create($file_dir);
        $filename =  '/' . $file_dir . implode('',$params) . '.png';
        $file_path = ROOT_PATH . '/public/' . $filename;

        \PHPQRCode\QRcode::png($params_str, $file_path, 'L', 4, 2);
        return $filename;
    }

}